package edu.usc.featureextractor;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Properties;

import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.rnn.RNNCoreAnnotations;
import edu.stanford.nlp.sentiment.SentimentCoreAnnotations;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeCoreAnnotations;
import edu.stanford.nlp.util.CoreMap;
import edu.usc.utils.FileUtils;

public class FeatureExtractor {
	public static String fUrl = "C:\\Ramesh\\works\\projects\\java_ws\\StorySummerizer\\trainingsummary\\";
	public static StanfordCoreNLP pipelineSentiment = null;
	public static StanfordCoreNLP pipelineParse = null;

	public static ArrayList<String> noneList = new ArrayList<>();
	public static ArrayList<String> ccList = new ArrayList<>();
	public static ArrayList<String> crList = new ArrayList<>();
	public static ArrayList<String> drList = new ArrayList<>();
	public static ArrayList<String> erList = new ArrayList<>();
	public static ArrayList<String> hrList = new ArrayList<>();
	public static ArrayList<String> rmList = new ArrayList<>();
	public static ArrayList<String> scList = new ArrayList<>();
	public static ArrayList<String> sellList = new ArrayList<>();
	public static ArrayList<String> selrList = new ArrayList<>();
	public static ArrayList<String> srList = new ArrayList<>();
	public static ArrayList<String> soclList = new ArrayList<>();
	public static ArrayList<String> suList = new ArrayList<>();

	public static ArrayList<String> precontemplationToContemplation = new ArrayList<>();
	public static ArrayList<String> contemplationToPreparation = new ArrayList<>();
	public static ArrayList<String> preparationToAction = new ArrayList<>();
	public static ArrayList<String> actionToMaintanence = new ArrayList<>();

	public static void test(boolean counts, boolean sentiment) {
		HashMap<String, Double> stats1 = null;
		HashMap<String, Double> stats2 = null;
		HashMap<String, Double> stats3 = null;
		HashMap<String, Double> stats4 = null;
		if (sentiment) {
			stats1 = printSentimentStats("PRECONTEMPLATION");
			stats2 = printSentimentStats("CONTEMPLATION");
			stats3 = printSentimentStats("PREPARATION");
			stats4 = printSentimentStats("ACTION");
		}
		if (counts) {
			System.out.println("This is so bad"+ getSentiment("This is so bad"));
			System.out.println("This is so good" + getSentiment("This is so good"));
			System.out.println("This is very good"+ getSentiment("This is very good"));
			System.out.println("This is not so good" + getSentiment("This is not so good"));
			System.out.println("This is very bad"+ getSentiment("This is very bad"));
			System.out.println("Today is Wednesday" + getSentiment("Today is Wednesday"));
			System.out.println("Today is Thursday" + getSentiment("Today is Thursday"));
			System.out.println("This is a movie" + getSentiment("This is a movie"));
			System.out.println("My name is Ramesh" + getSentiment("My name is Ramesh"));
			System.out.println("None size : " + noneList.size());
			System.out.println("CC size : " + ccList.size());
			System.out.println("CR size : " + crList.size());
			System.out.println("DR size : " + drList.size());
			System.out.println("ER size : " + erList.size());
			System.out.println("HR size : " + hrList.size());
			System.out.println("RM size : " + rmList.size());
			System.out.println("SC size : " + scList.size());
			System.out.println("SelL size : " + sellList.size());
			System.out.println("SelR size : " + selrList.size());
			System.out.println("SR size : " + srList.size());
			System.out.println("SocL size : " + soclList.size());
			System.out.println("SU size : " + suList.size());
			System.out.println("=============================");
			System.out.println("PC TO C size : " + precontemplationToContemplation.size());
			System.out.println("C TO PREP size : " + contemplationToPreparation.size());
			System.out.println("PREP TO A size : " + preparationToAction.size());
			System.out.println("A TO M size : " + actionToMaintanence.size());

			System.out.println("PC STATS: "+stats1); 
			System.out.println("C STATS: "+stats2);
			System.out.println("PR STATS: "+stats3);
			System.out.println("A STATS: "+stats4);
		}

		//printPOCorSOCList("ACTION", true);
	}

	public static void main(String[] args) {
		ArrayList<String> fif = FileUtils.listAllFilesInDirectory(fUrl);
		ArrayList<String> lines = new ArrayList<>();
		fileParser(fif, lines);
		System.out.println(lines.size());
		sentences(lines);

		precontemplationToContemplation.addAll(crList);
		precontemplationToContemplation.addAll(drList);
		precontemplationToContemplation.addAll(erList);
		precontemplationToContemplation.addAll(soclList);

		contemplationToPreparation.addAll(srList);
		contemplationToPreparation.addAll(selrList);

		preparationToAction.addAll(sellList);
		preparationToAction.addAll(hrList);
		preparationToAction.addAll(ccList);
		preparationToAction.addAll(suList);

		actionToMaintanence.addAll(rmList);
		actionToMaintanence.addAll(scList);

		Properties props = new Properties();
		props.setProperty("annotators", "tokenize, ssplit, parse, sentiment");
		pipelineSentiment = new StanfordCoreNLP(props);

		//test(false, false);
		test(true, true);

	}

	public static 

	public static HashMap<String, Double> printSentimentStats(String pocORsoc) {
		ArrayList<Integer> sentiments = getSentimentsForClass(pocORsoc);
		Integer sum = 0;
		for (Integer i: sentiments) {
			sum += i;
		}

		Collections.sort(sentiments);
		double average = (double)sum/(double)sentiments.size();
		double min = sentiments.get(0);
		double max = sentiments.get(sentiments.size()-1);
		double median = sentiments.get(sentiments.size()/2);
		HashMap<String, Double> toRet = new HashMap<>();
		toRet.put("AVERAGE", average);
		toRet.put("MIN", min);
		toRet.put("MAX", max);
		toRet.put("MEDIAN", median);
		toRet.put("0s", (double) Collections.frequency(sentiments, 0));
		toRet.put("1s", (double) Collections.frequency(sentiments, 1));
		toRet.put("2s", (double) Collections.frequency(sentiments, 2));
		toRet.put("3s", (double) Collections.frequency(sentiments, 3));
		toRet.put("4s", (double) Collections.frequency(sentiments, 4));
		toRet.put("0%", (double) Collections.frequency(sentiments, 0)/(double)sentiments.size());
		toRet.put("1%", (double) Collections.frequency(sentiments, 1)/(double)sentiments.size());
		toRet.put("2%", (double) Collections.frequency(sentiments, 2)/(double)sentiments.size());
		toRet.put("3%", (double) Collections.frequency(sentiments, 3)/(double)sentiments.size());
		toRet.put("4%", (double) Collections.frequency(sentiments, 4)/(double)sentiments.size());

		return toRet;
	}

	public static ArrayList<Integer> getSentimentsForClass(String pocOrsoc) {
		ArrayList<String> temp = new ArrayList<>();
		switch (pocOrsoc) {
		case "PRECONTEMPLATION":
			copyList(temp, precontemplationToContemplation);
			break;
		case "CONTEMPLATION":
			copyList(temp, contemplationToPreparation);
			break;
		case "PREPARATION":
			copyList(temp, preparationToAction);
			break;
		case "ACTION":
			copyList(temp, actionToMaintanence);
			break;
		case "CC":
			copyList(temp, ccList);
			break;
		case "CR":
			copyList(temp, crList);
			break;
		case "DR":
			copyList(temp, drList);
			break;
		case "ER":
			copyList(temp, erList);
			break;
		case "HR":
			copyList(temp, hrList);
			break;
		case "RM":
			copyList(temp, rmList);
			break;
		case "SC":
			copyList(temp, scList);
			break;
		case "SelfL":
			copyList(temp, sellList);
			break;
		case "SelfR":
			copyList(temp, selrList);
			break;
		case "SocL":
			copyList(temp, soclList);
			break;
		case "SU":
			copyList(temp, suList);
			break;
		case "None":
			copyList(temp, noneList);
			break;
		default:
			System.out.println("--- INVALID DEF ---");
			break;
		}
		ArrayList<String> clean = new ArrayList<>();
		for (String tempS: temp) {
			clean.add(FileUtils.cleanString(tempS));
		}

		ArrayList<Integer> sentiments = new ArrayList<>();
		for (String cleanS : clean) {
			sentiments.add(getSentiment(cleanS));
		}
		return sentiments;
	}		

	public static int getSentiment(String line) {

		int mainSentiment = 0;

		if (line != null && line.length() > 0) {
			int longest = 0;
			Annotation annotation = pipelineSentiment.process(line);
			for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) {
				Tree tree = sentence.get(SentimentCoreAnnotations.AnnotatedTree.class);
				int sentiment = RNNCoreAnnotations.getPredictedClass(tree);
				String partText = sentence.toString();
				if (partText.length() > longest) {
					mainSentiment = sentiment;
					longest = partText.length();
				}
			}
		}
		return mainSentiment;
	}

	public static void printPOCorSOCList(String poc, boolean sentiments) {
		switch (poc) {
		case "PRECONTEMPLATION":
			printList(precontemplationToContemplation, sentiments);
			break;
		case "CONTEMPLATION":
			printList(contemplationToPreparation, sentiments);
			break;
		case "PREPARATION":
			printList(preparationToAction, sentiments);
			break;
		case "ACTION":
			printList(actionToMaintanence, sentiments);
			break;
		case "CC":
			printList(ccList, sentiments);
			break;
		case "CR":
			printList(crList, sentiments);
			break;
		case "DR":
			printList(drList, sentiments);
			break;
		case "ER":
			printList(erList, sentiments);
			break;
		case "HR":
			printList(hrList, sentiments);
			break;
		case "RM":
			printList(rmList, sentiments);
			break;
		case "SC":
			printList(scList, sentiments);
			break;
		case "SelfL":
			printList(sellList, sentiments);
			break;
		case "SelfR":
			printList(selrList, sentiments);
			break;
		case "SocL":
			printList(soclList, sentiments);
			break;
		case "SU":
			printList(suList, sentiments);
			break;
		case "None":
			printList(noneList, sentiments);
			break;
		default:
			System.out.println("--- INVALID DEF ---");
			break;
		}
	}

	public static void printList(ArrayList<String> list, boolean sentiments) {
		for (int i=0; i < list.size(); i++) {
			if (sentiments) {
				System.out.println(i + " : "+ getSentiment(list.get(i)) +" : "+list.get(i));
			} else {
				System.out.println(i + " : "+list.get(i));
			}
		}
	}

	public static void sentences(ArrayList<String> lines) {
		for (String line: lines) {
			//System.out.println(line.split("\t")[1] +"\t"+line.split("\t")[2]);
			String lineNow = line.split("\t")[1];
			switch(line.split("\t")[2]) {
			case "CC":
				ccList.add(lineNow);
				//System.out.println("CC --" + line.split("\t")[2]);			
				break;
			case "CR":
				//System.out.println("CR --" + line.split("\t")[2]);
				crList.add(lineNow);
				break;
			case "DR":
				//System.out.println("DR --" + line.split("\t")[2]);
				drList.add(lineNow);
				break;
			case "ER":
				//System.out.println("ER --" + line.split("\t")[2]);
				erList.add(lineNow);
				break;
			case "HR":
				//System.out.println("HR --" + line.split("\t")[2]);
				hrList.add(lineNow);
				break;
			case "RM":
				//System.out.println("RM --" + line.split("\t")[2]);
				rmList.add(lineNow);
				break;
			case "SC":
				//System.out.println("SC --" + line.split("\t")[2]);
				scList.add(lineNow);
				break;
			case "SelfL":
				sellList.add(lineNow);
				//System.out.println("SelfL --" + line.split("\t")[2]);
				break;
			case "SelfR":
				selrList.add(lineNow);
				//System.out.println("SelfR --" + line.split("\t")[2]);
				break;
			case "SocL":
				soclList.add(lineNow);
				//System.out.println("SocL --" + line.split("\t")[2]);
				break;
			case "SU":
				suList.add(lineNow);
				//System.out.println("SU --" + line.split("\t")[2]);
				break;
			case "None":
				noneList.add(lineNow);
				//System.out.println("None --" + line.split("\t")[2]);
				break;
			default:
				//System.out.println("--- DEF ---"+line.split("\t")[2]);
				break;
			}
		}
	}

	public static void fileParser(ArrayList<String> files, ArrayList<String> lines) {
		for (String file: files) {
			ArrayList<String> linesTemp = FileUtils.contentsOfTheFileAsList(file);
			lines.addAll(linesTemp);
		}
	}

	public static void copyList(ArrayList<String> dest, ArrayList<String> source) {
		for (String s : source) {
			dest.add(s);
		}
	}
}

